public class LeadTriggerHandler{
    public void processInsertTrigger(List<sObject> listNewSo){
        List<Lead> listNewLead = (List<Lead>)listNewSo;
        //get the lead record type id and names
        List<RecordType> rtypes = [Select Name, Id,DeveloperName From RecordType where sObjectType='Lead' and isActive=true];
        ValidateLeadOnUpload_Temp(listNewLead,rtypes);
        UpdateCatalogField(listNewLead,rtypes);
    } 
    
    public void processUpdateTrigger(List <sObject> listNewSo){
        List<Lead>listNewLead = (List<Lead>)listNewSo;
        //get the lead record type id and names
        List<RecordType> rtypes = [Select Name, Id,DeveloperName From RecordType where sObjectType='Lead' and isActive=true];
        UpdateCatalogField(listNewLead,rtypes);
    }
    
    //*******************************************
    //Trigger 3: West - Employer CRPL Stuff
    //*******************************************    
    public void doUpdateSourceDetailField(List<Lead> lst_NewLead)
    {
        Map<Id,RecordType> map_RecordType = new Map<Id,RecordType>([ Select Id, DeveloperName from RecordType Where sObjectType='Lead' AND (DeveloperName='West_Prospective_Student' )]);
        
        String recTypeid;
        if(map_RecordType.size()>0)
        {
            recTypeid = map_RecordType.values()[0].Id;
        }

        Set<Id> set_EmployerIds = new Set<Id>();
        for(Lead l : lst_NewLead)
        {
            if(l.LeadSource!= null && l.LeadSource == 'CRPL' && l.Employer__c != null && l.RFI_Landing_Page__c != null && l.RecordTypeId == rectypeid)
            {
                set_EmployerIds.add(l.Employer__c);
            }
        }
        if(set_EmployerIds.size()>0)
        {
            Map<ID,Employer__c> map_employer  = new map<Id,Employer__c>([ Select Id,CEL_User__c from Employer__c where ID IN : set_EmployerIds]);
            for(Lead l : lst_NewLead)
            {
                if(l.LeadSource!= null && l.LeadSource == 'CRPL' && l.Employer__c != null && l.RFI_Landing_Page__c != null && l.RecordTypeId == rectypeid)
                {
                    l.Lead_Source_Detail__c = map_employer.get(l.Employer__c).CEL_User__c;
                }
            }
        }
    }
    
    //**************************************************
    //Trigger 1: ValidateLeadOnUpload Functionality
    //**************************************************   
    public void ValidateLeadOnUpload_Temp(List<Lead> listNewLead,List<RecordType> rtypes) {
     
     	//Changes for CPRL and CEL User
     	 Map<Id,RecordType> map_RecordType = new Map<Id,RecordType>([ Select Id, DeveloperName from RecordType Where sObjectType='Lead' AND (DeveloperName='West_Prospective_Student' )]);
        
        String recTypeid;
        if(map_RecordType.size()>0)
        {
            recTypeid = map_RecordType.values()[0].Id;
        }
     	
     	
        Integer testCount = 0;
        Integer testCount2 = 0;
    	system.debug('got here111');
        //STEP 1: Recordtype Mapping with S-Objects
        String recordTypeName=null;
        Map<String,String> leadRecordTypes = new Map<String,String>{};
        Set<String> sRectype = new Set<String>();
        for(RecordType rt: rtypes){
            leadRecordTypes.put(rt.Id,rt.Name);
            if(rt.DeveloperName == 'ULA_Traditional_Prospect' || rt.DeveloperName == 'ULA_Working_Adults_Prospect')
            {
                sRectype.add(rt.Id);
            }
        }
        List<RecordType> allRecTypeList= [SELECT Id, Name, SobjectType from RecordType where (SobjectType='Campaign' OR SobjectType='School__c' OR SobjectType='Employer__c' OR SobjectType='Program__c' OR SobjectType='Country__c' OR SobjectType='Campus__c' OR SobjectType='Mode__c') AND 
                                                                        IsActive = true];
		
        //get the mode record type and its records 
        List<Mode__c> modeList = [Select id, Name, recordType.name from Mode__c];
        Map<string,Mode__c> modeMap = new Map<string,Mode__c>();
        for(Mode__c mode : modeList)
        {
        	modeMap.put(mode.Name.toLowerCase(),mode);
        } 
        
        //get the campus record type and its records  
        List<Campus__c> campusList = [Select id, Name, recordType.name from Campus__c];
        Map<string,Campus__c> campusMap = new Map<string,Campus__c>();
        for(Campus__c campus : campusList)
        {
        	campusMap.put(campus.Name.toLowerCase(),campus);
        }
        
        //get the country record type and its records  
        List<Country__c> countryList=[Select id, Name, recordType.name from Country__c];
        Map<string,Country__c> countryMap = new Map<string,Country__c>();
        for(Country__c coun : countryList)
        {
        	countryMap.put(coun.Name.toLowerCase(),coun);
        }
        
        // get the program record type and  its records  
        List<Program__c> programList=[Select id, Name,External_ID_1__c, recordType.name from Program__c];
        Map<string,Program__c> programMap = new Map<string,Program__c>();
        Map<string,Program__c> progMapWest = new Map<string,Program__c>();
        for(Program__c prog: programList)
        {
        	programMap.put(prog.Name.toLowerCase(),prog);
        	
        	if(prog.External_ID_1__c != null)
        		progMapWest.put(prog.External_ID_1__c.toLowerCase(),prog);
        }
        
        //get the employer record type and its records  
        List<Employer__c> empList=[Select id, Name,CEL_User__c, recordType.name from Employer__c 
                                                                where recordType.name!=null];
		Map<string,Employer__c> empMap = new Map<string,Employer__c>();		                                                                
        Set<String> setEmpNames = new Set<String>();
        for(Employer__c emp: empList)
        {
            if(emp.name != null)
            {
            	setEmpNames.add(emp.name.toUpperCase());
            	empMap.put(emp.name.toLowerCase(),emp);	
            }            
        }
        
        //get the School and its records  
        List<School__c> schList=new List<School__c>([Select id, Name,recordType.name from School__c]);
        Map<string, School__c> schMap = new Map<string, School__c>();                
        Set<String> setSchoolNames = new Set<String>();
        for(School__c sch: schList)
        {
            if(sch.name != null)
            {
            	setSchoolNames.add(sch.name.toUpperCase());
            	schMap.put(sch.name.toLowerCase(), sch);	
            }
        }       
        
        List<User> userList = [Select Id, Name From User Where IsActive = true AND (UserRole.DeveloperName LIKE '%Enrollment_Counselor' OR UserRole.DeveloperName LIKE '%Enrollment_Coordinator')];
        Map<string,User> userMap = new Map<string,User>();
        for(User user: userList)
        {
        	userMap.put(user.Name.toLowerCase(),user);
        }
        
        //get the campaing details so as to check the Campaign member text        
        List<Campaign> campaignList = [select id,RecordTypeId,RecordType.Name,CNID__c from Campaign];
        Map<string,Campaign> campaignMap = new Map<string,Campaign>();
        for(Campaign camp : campaignList)
        {
        	campaignMap.put(camp.CNID__c,camp);
        } 
        
        //getting the tenant short name values from the Tenants__c List Custom Setting
        List<Tenants__C> tenantList = Tenants__c.getall().values();   
            
           
        //STEP 2: LOOKUP MATCHING CRITERIA CHECK ENDS
        for (Lead leadRecord: listNewLead) 
        {     
        	testCount2++;           
            recordTypeName=leadRecordTypes.get(leadRecord.RecordTypeId);
            system.debug('leadRecord');    
            system.debug(leadRecord.Id);
            system.debug('leadRecordId');  
            
            if(leadRecord.School_Text__c != null && !setSchoolNames.contains(leadRecord.School_Text__c.toUppercase()) && recordTypeName.contains('ULA') && Trigger.new.size()>1)
            {
                leadRecord.addError('School Name is not Correct for Feeder School');
            }
            
            if(sRectype.Contains(leadRecord.RecordTypeId) && Trigger.new.size()>1 && leadRecord.Employer__c != null && recordTypeName.contains('ULA') && !setEmpNames.contains(leadRecord.Employer_Text__c.toUpperCase() ))
            {           
                leadRecord.addError('Employer is not Correct for the Lead');
            }
            
            for(Tenants__C te:tenantList)
            {   
                //check whether the lead record type contains the tenant short name
                if(recordTypeName.contains(te.Tenant_Short_Name__c))
                 {                 
                 	testCount++ ;
                    system.debug('$$$$$$ How many times tenants run ' + testCount );
                    /* Merge all Tenant to One: sObjRecType*/                    
                    for(RecordType sObjRecType: AllRecTypeList)
                    {
                    	if(sObjRecType.name.contains(te.Tenant_Short_Name__c))
                        {
                        	system.debug('I reached into tenant');
                        	system.debug(te.Tenant_Short_Name__c);
                            system.debug(sObjRecType.SobjectType);
                            if(sObjRecType.SobjectType == 'Mode__c')
                            {
                            	system.debug('got to mode outside');                            	
                                if((leadRecord.Mode_Text__c!=null))
                                {
                                	if(modeMap.containsKey(leadRecord.Mode_Text__c.toLowerCase()))
                                	{
                                		Mode__c tempMode = modeMap.get(leadRecord.Mode_Text__c.toLowerCase());
                                		if(tempMode.RecordType.Name.equals(sObjRecType.name))
                                        {
                                            leadRecord.Mode__c=null;
                                            leadRecord.Mode__c=tempMode.Id;
                                            System.debug('$$$$$$$$$$$$$$ line 143 ' + tempMode.Id );
                                         }
                                      }    
                                  }
                              }
                              
                            //Campus lookup id population    
                            else if(sObjRecType.SobjectType == 'Campus__c')
                            {
                            	system.debug('got to campus outside');
                                if((leadRecord.Campus_Text__c!=null))
                                {
                                	if(campusMap.containsKey(leadRecord.Campus_Text__c.toLowerCase()))
                                	{
                                		Campus__c tempCampus = campusMap.get(leadRecord.Campus_Text__c.toLowerCase());
                                		if(tempCampus.RecordType.Name.equals(sObjRecType.name))
                                        {
                                            leadRecord.Campus__c=null;
                                            leadRecord.Campus__c=tempCampus.Id;
                                            System.debug('$$$$$$$$$$$$$$ line 165 ' + tempCampus.Id);
                                        }
                                    }
                                }
                            }
                            //Country Of Birth lookup id population and Country of Residence lookup id population
                            else if(sObjRecType.SobjectType == 'Country__c')
                            {
                               system.debug(sObjRecType.SobjectType );
                               system.debug('Got Here9');
                               if((leadRecord.Country_of_Birth_Text__c!=null))
                               {
                               		if(countryMap.containsKey(leadRecord.Country_of_Birth_Text__c.toLowerCase()))
                                    {
                                    	Country__c tempCountryBirth = countryMap.get(leadRecord.Country_of_Birth_Text__c.toLowerCase());
                                        if(tempCountryBirth.RecordType.Name.equals(sObjRecType.name))
                                        {
                                        	leadRecord.Country_Of_Birth__c=null;
                                            leadRecord.Country_of_Birth__c=tempCountryBirth.Id;                                            
                                       	}
                                     }
                                     
                                }
                                if((leadRecord.Country_of_Residence_Text__c!=null))
                                {
                                	if(countryMap.containsKey(leadRecord.Country_of_Residence_Text__c.toLowerCase())) 
                                    {
                                    	Country__c tempCountryResidence = countryMap.get(leadRecord.Country_of_Residence_Text__c.toLowerCase());
                                        if(tempCountryResidence.RecordType.Name.equals(sObjRecType.name))
                                        {
                                        	leadRecord.Country_of_Residence__c=null;
                                            leadRecord.Country_of_Residence__c=tempCountryResidence.Id;
                                        }
                                     }
                                }
                            }
                            
                            //Program lookup id population 
                            else if(sObjRecType.SobjectType == 'Program__c')
                            {
                            	system.debug('Got Here to program');                               	
                                if((leadRecord.Program_Text__c!=null))
                                {
                                	system.debug('$$$$$$$$$$$$$$ line 225 ' + leadRecord.Program_Text__c);
                                    Program__c tempProgram;
                                    if(programMap.ContainsKey(leadRecord.Program_Text__c.toLowerCase())) {
                                    	tempProgram = programMap.get(leadRecord.Program_Text__c.toLowerCase());
                                        if(tempProgram.RecordType.Name.equals(sObjRecType.name))
                                        {
                                        	leadRecord.Program__c=null;
                                            leadRecord.Program__c=tempProgram.Id;
                                        }
                                     }
                                     else if (progMapWest.ContainsKey(leadRecord.Program_Text__c.toLowerCase())) {
                                     	tempProgram = progMapWest.get(leadRecord.Program_Text__c.toLowerCase());
                                        if(tempProgram.RecordType.Name.equals(sObjRecType.name))
                                        {
                                        	leadRecord.Program__c=null;
                                            leadRecord.Program__c=tempProgram.Id;
                                        }
                                     }
                                 }
                                 
                            }
                            
                            //Employer lookup id population
                            else if(sObjRecType.SobjectType == 'Employer__c')
                            {
                            	system.debug('Got Here5');
                                //System.debug('$$$$$$$$$$$$$$ line 243 ' + sObjRecType.SobjectType );
                                if((leadRecord.Employer_Text__c!=null))
                                {
                                 	if(empMap.containsKey(leadRecord.Employer_Text__c.toLowerCase()))
                                    {
                                    	Employer__c tempEmployer = empMap.get(leadRecord.Employer_Text__c.toLowerCase());
                                    	if(tempEmployer.RecordType.Name.equals(sObjRecType.name))
                                    	{
                                     		leadRecord.Employer__c=null;
                                        	leadRecord.Employer__c=tempEmployer.Id;
                                            system.debug('$$$$$$$$$$$$$$ line 249 ' + tempEmployer.Id);
                                            if(leadRecord.LeadSource == 'CRPL' && leadRecord.LeadSource!= null && leadRecord.Employer__c != null && leadRecord.RFI_Landing_Page__c != null && leadRecord.RecordTypeId == rectypeid)
                                            {
                                                leadRecord.Lead_Source_Detail__c = tempEmployer.CEL_User__c;
                                            }
                                        }
                                    }    
                                }    
                            }
                          
                            //School lookup id population
                            else if(sObjRecType.SobjectType == 'School__c')
                            {
                            	system.debug('Got Here1');                                
                                if((leadRecord.School_Text__c!=null))
                                {
                                	system.debug('Got Here2');
                                	if(schMap.ContainsKey(leadRecord.School_Text__c.toLowerCase()))
                                	{
                                		School__c tSch = schMap.get(leadRecord.School_Text__c.toLowerCase());
                                		if(tSch.RecordType.Name.equals(sObjRecType.name))
                                		{
                                			system.debug('test2345');
                                			leadRecord.Feeder_School__c=null;
                                            leadRecord.Feeder_School__c=tSch.Id;
                                            system.debug(tSch.Id);   
                                		}
                                	}
                                }
                            }
                            //break;
                        }
                    }              
                    system.debug('Got Here10');
                    if((leadRecord.Enrollment_Counselor_Lead_Finder_Text__c != null))
                    {
                    	system.debug('Got Here3');
                        if(userMap.containsKey(leadRecord.Enrollment_Counselor_Lead_Finder_Text__c.toLowerCase()))
                        {
                        	User tempUser = userMap.get(leadRecord.Enrollment_Counselor_Lead_Finder_Text__c.toLowerCase());
                        	leadRecord.Enrollment_Counselor_Lead_Finder__c=null;
                            leadRecord.Enrollment_Counselor_Lead_Finder__c=tempUser.Id;
                        }
                    }
                    if(leadRecord.Campaign_Text__c!=null)
                    {  
                        boolean recValid=false;
                        for(RecordType camRecType:  AllRecTypeList)
                        {
                            if(camRecType.name.contains(te.Tenant_Short_Name__c) && camRecType.SobjectType == 'Campaign')
                            {
                                if(campaignMap.containsKey(leadRecord.Campaign_Text__c))
                                { 
                                	Campaign tempCampaign = campaignMap.get(leadRecord.Campaign_Text__c);
                                	if(tempCampaign.RecordType.Name.equals(camRecType.name))
                                    {
                                        recValid = true;
                                        break;  
                                     }
                                }
                             }
                        }
                        if(recValid ==false){
                            leadRecord.Campaign_Text__c.addError('Invalid Campaign CNID');  
                            //break;                                 
                        }
                    } 
				}
            }
        }
    }
    
    //************************************************
    //Trigger 2: UpdateCatalogField Functionality
    //************************************************
    public void UpdateCatalogField(List<Lead> listNewLead,List<RecordType> rtypes){
        String recordTypeName = null;
    
        Map<String,String> leadRecordTypes = new Map<String,String>{};
        for(RecordType rt: rtypes){
           leadRecordTypes.put(rt.Id,rt.DeveloperName);
        }
        System.debug('====Lead record types: ' + leadRecordTypes);

        /*get the catalog record type and its records */
        Map<Id, Catalog__c> ctList=new Map<Id, Catalog__c>([Select id, Name, recordTypeId, Campus__c, Program__c, RecordType.DeveloperName from Catalog__c]);
        System.debug('====Catalog records: ' + ctList.size());
        Map<String, String> mapLeadToCatalog = new Map<String, String>();
        List<LeadToCatalogRecordTypes__c> listCS = LeadToCatalogRecordTypes__c.getAll().values();
        System.debug('====Custom Settings size: ' + listCS.size());
        for(Integer nCount = 0; nCount < listCS.size(); nCount++){
            System.debug('====Custom Setting - Lead Rec Type: ' + listCS[nCount].LeadRecordType__c);
            System.debug('====Custom Setting - Catalog Rec Type: ' + listCS[nCount].CatalogRecordType__c);
            mapLeadToCatalog.put(listCS[nCount].LeadRecordType__c, listCS[nCount].CatalogRecordType__c);
        }
        System.debug('====Lead To Catalog: ' + mapLeadToCatalog);
        for (Lead leadRecord:listNewLead) 
        {        
            recordTypeName=leadRecordTypes.get(leadRecord.RecordTypeId);
            System.debug('====Lead Record Type Name: ' + recordTypeName);
            system.debug('leadRecord');    
            system.debug(leadRecord.Id);
            system.debug('leadRecordId');    
            //getting the tenant short name values from the Tenants__c List Custom Setting
            System.debug('====Lead Campus: ' + leadRecord.Campus__c);
            System.debug('====Lead Program: ' + leadRecord.Program__c);
            System.debug('====Lead Campus: ' + leadRecord.Campus_Text__c);
            System.debug('====Lead Program: ' + leadRecord.Program_Text__c);
                    
            /*Catalog lookup id population*/               
            if((leadRecord.Campus__c != null) && (leadRecord.Program__c != null))
            {           
                String strLeadRecordTypeName = leadRecordTypes.get(leadRecord.recordTypeId);
                System.debug('****Lead Record Type Name: ' + strLeadRecordTypeName);
                String strCatalogRecordTypeName = mapLeadToCatalog.get(strLeadRecordTypeName);
                System.debug('****CatalogRecodTypeMapped: ' + strCatalogRecordTypeName);
                // Error if no matching catalog found
                Boolean bFound = false;
                for(Catalog__c ct : ctList.values())
                {
                    System.debug('Campus Match: ' + (ct.Campus__c == leadRecord.Campus__c));
                    System.debug('Program Match: ' + (ct.Program__c == leadRecord.Program__c));
                    System.debug('Record Type Match: ' + (ct.RecordType.DeveloperName == strCatalogRecordTypeName));
                    System.debug('Catalog Rec Type: ' + ct.RecordTypeId);
                    if((ct.Campus__c == leadRecord.Campus__c) && 
                        (ct.Program__c == leadRecord.Program__c)&& 
                        (ct.RecordType.DeveloperName == strCatalogRecordTypeName))
                    {
                        leadRecord.Catalog__c=null;
                        leadRecord.Catalog__c=ct.Id;
                        System.debug('****Lead Catalog: ' + ct.Name);
                        bFound = true;
                    }
                }    
                if (bFound == false && strLeadRecordTypeName.contains('ULA')){
                    System.debug('====Error: Invalid Campus and Program selection. No catalog found for selected Campus and Program.');
                    leadRecord.Catalog__c.addError('Invalid Campus and Program selection. No catalog found for selected Campus and Program.');
                }
            }    
        }
    }
}